<?php

    class WZ_Date extends Zend_Date
    {
        /**
         * Constructor
         * @param  string|integer|Zend_Date|array  $date    OPTIONAL Date value or value of date part to set
         *                                                 ,depending on $part. If null the actual time is set
         * @param  string                          $part    OPTIONAL Defines the input format of $date
         * @param  string|Zend_Locale              $locale  OPTIONAL Locale for parsing input
         * @return WZ_Date
         * @throws Zend_Date_Exception
         */
        public function __construct($date = null, $part = null, $locale = null)
        {
            if (null === $locale) {
                $locale = WZ_Locale::getLocale();
            }
            // supress notice about PCRE without UTF8 support
            @parent::__construct($date, $part, $locale);
        }

        /**
         * Returns a clone of $this, with the time part set to 00:00:00.
         *
         * @param  string|Zend_Locale  $locale  OPTIONAL Locale for parsing input
         * @return WZ_Date
         */
        public function getDate($locale = null)
        {
            // supress notice about PCRE without UTF8 support
            return @parent::getDate($locale);
        }

        /**
         * Returns the WZ_Date with determined timestamp
         *
         * @static
         * @param  int     $timestamp Unix timestamp
         * @return WZ_Date
         */
        public static function timestamp($timestamp)
        {
            return new WZ_Date($timestamp);
        }

        /**
         * Returns the actual date as string
         *
         * @static
         * @param  string|Zend_Locale        $locale  OPTIONAL Locale for parsing input
         * @return WZ_Date
         */
        public static function now($locale = null)
        {
            return new WZ_Date(time(), self::TIMESTAMP, $locale);
        }

        /**
         * set timezone
         *
         * @param null | string
         * @return Zend_Date_DateObject  Provides fluent interface
         */
        public function setTimezone($timezone = null)
        {
            if (null === $timezone) {
                $timezone = WZ_Locale::getDefaultTimezone();
            }
            try {
                return parent::setTimezone($timezone);
            } catch(Zend_Date_Exception $e) {
                return parent::setTimezone(WZ_Locale::DEFAULT_TIMEZONE);
            }
        }

        /**
         * @param  string              $format  OPTIONAL Rule for formatting output. If null the default date format is used
         * @param  string|Zend_Locale  $locale  OPTIONAL Locale for parsing input
         * @return string
         */
        public function toPhpString($format = null, $locale = null)
        {
            self::setTimezone(WZ_Locale::getDefaultTimezone());
            return $this->toString($format, 'php', $locale);
        }

        /**
         * Returns a string for sql request
         *
         * @param  string|Zend_Locale  $locale  OPTIONAL Locale for parsing input
         * @return string
         */
        public function toSQLString($locale = null)
        {
            self::setTimezone(WZ_Locale::getDefaultTimezone());
            return $this->toString('yyyy-MM-dd HH:mm:ss', 'iso', $locale);
        }

        /**
         * Returns this, change timestamp on day start time
         *
         * @return WZ_Date provides fluent interface
         */
        public function getStartDay()
        {
            $this->subDay(1);
            return $this->setTimestamp(mktime(
                23, 59, 59,
                $this->get(self::MONTH),
                $this->get(self::DAY),
                $this->get(self::YEAR)
            ));
        }

        /**
         * Returns this, change timestamp on week start time
         *
         * @return WZ_Date provides fluent interface
         */
        public function getStartWeek()
        {//@todo start week day as config option
            $this->subDay($this->get(Zend_Date::WEEKDAY_DIGIT));
            return $this->setTimestamp(mktime(
                23, 59, 59,
                $this->get(self::MONTH),
                $this->get(self::DAY),
                $this->get(self::YEAR)
            ));
        }

        /**
         * Returns this, change timestamp on month start time
         *
         * @return WZ_Date provides fluent interface
         */
        public function getStartMonth()
        {
            $prevMonth = $this->subMonth(1);
            return $this->setTimestamp(mktime(
                23, 59, 59,
                $prevMonth->get(self::MONTH),
                $prevMonth->get(self::MONTH_DAYS),
                $prevMonth->get(self::YEAR)
            ));
        }
    }